﻿using Framework;
using UnityEngine;

namespace Game
{
    public class GameObjectContainerEntity : CommonEntity
    {
        public GameObject gameObject { get; protected set; }
        public Transform transform { get; protected set; }

        public Vector3 position
        {
            get
            {
                return transform.position;
            }
            set
            {
                transform.position = value;
            }
        }

        public Vector3 localPosition
        {
            get
            {
                return transform.localPosition;
            }
            set
            {
                transform.localPosition = value;
            }
        }

        protected bool _isCompleted = false;
        protected GameObject _contentGameObject;
        protected Transform _contentTransform;

        private ResourceComponent _resourceComp;
        private string _url;

        public GameObjectContainerEntity()
        {
            gameObject = new GameObject("ContainerEntity");
            transform = gameObject.transform;
            _resourceComp = AddComponent<ResourceComponent>();
            _resourceComp.Completed += OnResLoadCompleted;
        }

        public override void Dispose()
        {
            Object.Destroy(gameObject);
            gameObject = null;
            transform = null;
            base.Dispose();
        }

        public void Load(string url)
        {
            Reset();
            _url = url;
            _resourceComp.Load(_url);
        }

        public void SetParent(Transform parent)
        {
            transform.SetParent(parent, false);
        }
        
        protected virtual void OnReset()
        { 
        }

        protected virtual void PreInstantiate()
        {
            OnPreInstantiateCompleted();
        }

        protected void OnPreInstantiateCompleted()
        {
            Instantiate();
        }

        protected virtual void PostInstantiate()
        {
            OnPostInstantiateCompleted();
        }

        protected void OnPostInstantiateCompleted()
        {
            _isCompleted = true;
            OnInstantiateCompleted();
            Emit(CommonEntityEvent.OnCompleted);
        }

        protected virtual void OnInstantiateCompleted()
        {
        }

        private void OnResLoadCompleted()
        {
            PreInstantiate();
        }

        private void Instantiate()
        {
            Resource mainResource = _resourceComp.GetResource(_url);
            _contentGameObject = Object.Instantiate(mainResource.GetAsset<GameObject>());
            _contentTransform = _contentGameObject.transform;
            _contentTransform.SetParent(transform, false);
            PostInstantiate();
        }

        private void Reset()
        {
            OnReset();
            if (_contentGameObject != null)
            {
                Object.Destroy(_contentGameObject);
                _contentGameObject = null;
                _contentTransform = null;
            }
            _url = null;
            _isCompleted = false;
            _resourceComp.Cancel();
        }
    }
}